﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace LightWadf.Util
{
    static class LogUtility
    {
        private static ConcurrentQueue<dynamic> Queue = new ConcurrentQueue<dynamic>();

        static LogUtility()
        {
            if (Utility.GlobalConfiguration.GlobalLogger == null)
            {
                return;
            }

            Task.Run(() =>
            {
                while (Queue != null)
                {
                    dynamic log = null;
                    if (Queue.TryDequeue(out log))
                    {
                        string level = log.Level;
                        if (!string.IsNullOrEmpty(level))
                        {
                            switch (level)
                            {
                                case "Trace":
                                    Utility.GlobalConfiguration.GlobalLogger.Trace(log.Message);
                                    break;
                                case "Debug":
                                    Utility.GlobalConfiguration.GlobalLogger.Debug(log.Message);
                                    break;
                                case "Error":
                                    Utility.GlobalConfiguration.GlobalLogger.Error(log.Exception, log.Message);
                                    break;
                                case "Fatal":
                                    Utility.GlobalConfiguration.GlobalLogger.Fatal(log.Exception, log.Message);
                                    break;
                                case "Info":
                                    Utility.GlobalConfiguration.GlobalLogger.Info(log.Message);
                                    break;
                                case "Warn":
                                    Utility.GlobalConfiguration.GlobalLogger.Warn(log.Message);
                                    break;
                                default:
                                    break;
                            }
                        }
                    }
                }
            });
        }

        public static void Trace(string message)
        {
            if (Utility.GlobalConfiguration.GlobalLogger != null)
            {
                var time = DateTime.Now;
                message = string.Format("{2}.{3} --- ThreadId: {0} --- Message: {1}", Thread.CurrentThread.ManagedThreadId, message, time.ToLongTimeString(), time.Millisecond);
                dynamic log = new ExpandoObject();
                log.Level = "Trace";
                log.Message = message;
                Queue.Enqueue(log);
            }
        }

        public static void Debug(string message)
        {
            if (Utility.GlobalConfiguration.GlobalLogger != null)
            {
                var time = DateTime.Now;
                message = string.Format("{2}.{3} --- ThreadId: {0} --- Message: {1}", Thread.CurrentThread.ManagedThreadId, message, time.ToLongTimeString(), time.Millisecond);
                dynamic log = new ExpandoObject();
                log.Level = "Debug";
                log.Message = message;
                Queue.Enqueue(log);
            }
        }

        public static void Error(Exception e, string message)
        {
            if (Utility.GlobalConfiguration.GlobalLogger != null)
            {
                var time = DateTime.Now;
                message = string.Format("{2}.{3} --- ThreadId: {0} --- Message: {1}", Thread.CurrentThread.ManagedThreadId, message, time.ToLongTimeString(), time.Millisecond);
                dynamic log = new ExpandoObject();
                log.Level = "Error";
                log.Exception = e;
                log.Message = message;
                Queue.Enqueue(log);
            }
        }

        public static void Fatal(Exception e, string message)
        {
            if (Utility.GlobalConfiguration.GlobalLogger != null)
            {
                var time = DateTime.Now;
                message = string.Format("{2}.{3} --- ThreadId: {0} --- Message: {1}", Thread.CurrentThread.ManagedThreadId, message, time.ToLongTimeString(), time.Millisecond);
                dynamic log = new ExpandoObject();
                log.Level = "Fatal";
                log.Exception = e;
                log.Message = message;
                Queue.Enqueue(log);
            }
        }

        public static void Info(string message)
        {
            if (Utility.GlobalConfiguration.GlobalLogger != null)
            {
                var time = DateTime.Now;
                message = string.Format("{2}.{3} --- ThreadId: {0} --- Message: {1}", Thread.CurrentThread.ManagedThreadId, message, time.ToLongTimeString(), time.Millisecond);
                dynamic log = new ExpandoObject();
                log.Level = "Info";
                log.Message = message;
                Queue.Enqueue(log);
            }
        }

        public static void Warn(string message)
        {
            if (Utility.GlobalConfiguration.GlobalLogger != null)
            {
                var time = DateTime.Now;
                message = string.Format("{2}.{3} --- ThreadId: {0} --- Message: {1}", Thread.CurrentThread.ManagedThreadId, message, time.ToLongTimeString(), time.Millisecond);
                dynamic log = new ExpandoObject();
                log.Level = "Warn";
                log.Message = message;
                Queue.Enqueue(log);
            }
        }
    }
}
